package top.ijiujiu.component;

import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;
import org.springframework.util.StringUtils;
import top.ijiujiu.entity.SysUser;
import top.ijiujiu.util.JwtTokenUtil;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * JWTAuthorizationFilter
 *
 * @Author 神秘的黄瓜
 * @Version 1.0
 * @Date 2020-06-28 15:30
 */
public class JWTAuthorizationFilter extends BasicAuthenticationFilter {


    public JWTAuthorizationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String tokenHeader = request.getHeader(JwtTokenUtil.TOKEN_HEADER);
        // 如果请求头中没有Authorization信息则直接放行了
        if (tokenHeader == null || !tokenHeader.startsWith(JwtTokenUtil.TOKEN_PREFIX)) {
            chain.doFilter(request, response);
            return;
        }
        // 如果请求头中有Token，则进行解析，并且设置认证信息
        SecurityContextHolder.getContext().setAuthentication(getAuthentication(tokenHeader));
        super.doFilterInternal(request, response, chain);
    }


    // 这里从Token中获取用户信息并新建一个Token
    private UsernamePasswordAuthenticationToken getAuthentication(String tokenHeader) {
        String token = tokenHeader.replace(JwtTokenUtil.TOKEN_PREFIX, "");
        SysUser user = JwtTokenUtil.getUserFromToken(token);
        String roles = JwtTokenUtil.getRolesFromToken(token);
        List<GrantedAuthority> authorities = new ArrayList<>();
        if (!StringUtils.isEmpty(roles)) {
            Set<String> set = StringUtils.commaDelimitedListToSet(roles);
            for (String s : set) {
                authorities.add(new SimpleGrantedAuthority(s));
            }
        }
        if (user != null){
            return new UsernamePasswordAuthenticationToken(user, "", authorities);
        }
        return null;
    }
}
